package com.demo.controller;

import com.demo.dao.OrderDao;
import com.demo.dao.VenueDao;
import com.demo.entity.Order;
import com.demo.entity.User;
import com.demo.entity.Venue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

import static org.hamcrest.Matchers.containsString;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.web.filter.CharacterEncodingFilter;
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Transactional
class OrderControllerIT {



    @TestConfiguration
    static class Utf8Config {
        @Bean
        public CharacterEncodingFilter characterEncodingFilter() {
            CharacterEncodingFilter filter = new CharacterEncodingFilter();
            filter.setEncoding("UTF-8");
            filter.setForceEncoding(true);
            return filter;
        }
    }

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private VenueDao venueDao;

    private MockHttpSession session;

    private Venue testVenue;

    @BeforeEach
    void setUp() {
        // 清空数据库
        orderDao.deleteAll();
        venueDao.deleteAll();

        // 插入测试场馆
        testVenue = new Venue(0, "测试场馆", "测试描述", 200, "/test.jpg", "测试地址", "08:00", "22:00");
        venueDao.save(testVenue);

        // 模拟登录用户
        User user = new User();
        user.setUserID("test_user");

        session = new MockHttpSession();
        session.setAttribute("user", user);
    }

    @Test
    void testOrderManagePageAuthenticated() throws Exception {
        mockMvc.perform(get("/order_manage").session(session))
                .andExpect(status().isOk())
                .andExpect(view().name("order_manage"));
    }

    @Test
    void testOrderListJsonInitiallyEmpty() throws Exception {
        mockMvc.perform(get("/getOrderList.do")
                        .param("page", "1")
                        .session(session))
                .andExpect(status().isOk())
                .andExpect(content().json("[]"));
    }

    @Test
    void testAddOrderThenList() throws Exception {
        mockMvc.perform(post("/addOrder.do")
                        .param("venueName", testVenue.getVenueName())  // Controller 根据场馆名找 venueID
                        .param("startTime", "2025-04-10 10:00")
                        .param("date", "")
                        .param("hours", "2")
                        .session(session))
                .andExpect(status().is3xxRedirection())
                .andExpect(redirectedUrl("order_manage"));

        assertEquals(1, orderDao.count());

        mockMvc.perform(get("/getOrderList.do")
                        .param("page", "1")
                        .session(session))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json"))  // 指定UTF-8
                .andExpect(content().string(containsString("测试场馆")));
    }

    @Test
    void testFinishOrder() throws Exception {
        Order order = new Order();
        order.setVenueID(testVenue.getVenueID());
        order.setUserID("test_user");
        order.setStartTime(LocalDateTime.now());
        order.setHours(2);
        order.setState(2); // 初始为“已审核”
        order.setOrderTime(LocalDateTime.now());
        order.setTotal(0);
        orderDao.save(order);
        orderDao.flush();

        int orderId = order.getOrderID();

        mockMvc.perform(post("/finishOrder.do")
                        .param("orderID", String.valueOf(orderId)))
                .andExpect(status().isOk());

        Order updated = orderDao.findById(orderId).orElse(null);
        assertEquals(2, updated.getState());
    }

    @Test
    void testDeleteOrder() throws Exception {
        Order order = new Order();
        order.setVenueID(testVenue.getVenueID());
        order.setUserID("test_user");
        order.setStartTime(LocalDateTime.now());
        order.setHours(2);
        order.setState(3); // 已完成
        order.setOrderTime(LocalDateTime.now());
        order.setTotal(0);
        orderDao.save(order);

        int orderId = order.getOrderID();

        mockMvc.perform(post("/delOrder.do")
                        .param("orderID", String.valueOf(orderId)))
                .andExpect(status().isOk())
                .andExpect(content().string("true"));

        assertEquals(0, orderDao.count());
    }
}
